From 517191540a2a9e5c2ccdf7d0952b4e34d65537e0 Mon Sep 17 00:00:00 2001 From: Factiven Date: Wed, 19 Apr 2023 17:24:31 +0700 Subject: client side rendering --- pages/anime/watch/[...info].js | 746 +++++++++++++++++++++++------------------ 1 file changed, 419 insertions(+), 327 deletions(-) (limited to 'pages/anime/watch/[...info].js') diff --git a/pages/anime/watch/[...info].js b/pages/anime/watch/[...info].js index cd63614..0b2bd35 100644 --- a/pages/anime/watch/[...info].js +++ b/pages/anime/watch/[...info].js @@ -1,10 +1,10 @@ import Image from "next/image"; -import VideoPlayer from "../../../components/videoPlayer"; import Link from "next/link"; import { closestMatch } from "closest-match"; import Head from "next/head"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import Modal from "../../../components/modal"; +import dynamic from "next/dynamic"; import { useNotification } from "../../../lib/useNotify"; @@ -14,23 +14,220 @@ import { authOptions } from "../../api/auth/[...nextauth]"; import AniList from "../../../components/media/aniList"; +import Skeleton, { SkeletonTheme } from "react-loading-skeleton"; +import "react-loading-skeleton/dist/skeleton.css"; + import { Navigasi } from "../.."; -export default function Info({ info, sessions, statusWatch }) { - const title = info.aniData.title.romaji || info.aniData.title.english; - const data = info.aniData; - const fallback = info.epiFallback; - const { Notification: NotificationComponent } = useNotification(); +const VideoPlayer = dynamic(() => + import("../../../components/videoPlayer", { ssr: false }) +); - let playingEpisode = data.episodes - .filter((item) => item.id == info.id) - .map((item) => item.number); +export default function Info({ sessions, id, aniId }) { + const [epiData, setEpiData] = useState(null); + const [data, setAniData] = useState(null); + const [fallback, setEpiFallback] = useState(null); + const [skip, setSkip] = useState({ op: null, ed: null }); + const [statusWatch, setStatusWatch] = useState("CURRENT"); + const [playingEpisode, setPlayingEpisode] = useState(null); + const [loading, setLoading] = useState(false); - if (playingEpisode == 0) { - playingEpisode = fallback - .filter((item) => item.id == info.id) - .map((item) => item.number); - } + // console.log(epiData); + + useEffect(() => { + const defaultState = { + epiData: null, + skip: { op: null, ed: null }, + statusWatch: "CURRENT", + playingEpisode: null, + loading: false, + }; + + // Reset all state variables to their default values + Object.keys(defaultState).forEach((key) => { + const value = defaultState[key]; + if (Array.isArray(value)) { + value.length + ? eval( + `set${ + key.charAt(0).toUpperCase() + key.slice(1) + }(${JSON.stringify(value)})` + ) + : eval(`set${key.charAt(0).toUpperCase() + key.slice(1)}([])`); + } else { + eval( + `set${key.charAt(0).toUpperCase() + key.slice(1)}(${JSON.stringify( + value + )})` + ); + } + }); + + const fetchData = async () => { + // setLoading(true); + let epiFallback = null; + + const res = await fetch( + `https://api.moopa.my.id/meta/anilist/watch/${id}` + ); + const epiData = await res.json(); + setEpiData(epiData); + + const res2 = await fetch( + `https://api.moopa.my.id/meta/anilist/info/${aniId}` + ); + const aniData = await res2.json(); + setAniData(aniData); + + if (aniData.episodes.length === 0) { + const res = await fetch( + `https://api.moopa.my.id/anime/gogoanime/${ + aniData.title.romaji || aniData.title.english + }` + ); + const data = await res.json(); + const match = closestMatch( + aniData.title.romaji, + data.results.map((item) => item.title) + ); + const anime = data.results.filter((item) => item.title === match); + if (anime.length !== 0) { + const infos = await fetch( + `https://api.moopa.my.id/anime/gogoanime/info/${anime[0].id}` + ).then((res) => res.json()); + epiFallback = infos.episodes; + } + setEpiFallback(epiFallback); + } + + let playingEpisode = aniData.episodes + .filter((item) => item.id == id) + .map((item) => item.number); + + if (playingEpisode == 0) { + playingEpisode = epiFallback + .filter((item) => item.id == id) + .map((item) => item.number); + } + + setPlayingEpisode(playingEpisode); + + const res4 = await fetch( + `https://api.aniskip.com/v2/skip-times/${aniData.malId}/${parseInt( + playingEpisode + )}?types[]=ed&types[]=mixed-ed&types[]=mixed-op&types[]=op&types[]=recap&episodeLength=` + ); + const skip = await res4.json(); + + const op = skip.results?.find((item) => item.skipType === "op") || null; + const ed = skip.results?.find((item) => item.skipType === "ed") || null; + + setSkip({ op, ed }); + + if (sessions) { + const response = await fetch("https://graphql.anilist.co/", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + query: ` + query ($username: String, $status: MediaListStatus) { + MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { + user { + id + name + about (asHtml: true) + createdAt + avatar { + large + } + statistics { + anime { + count + episodesWatched + meanScore + minutesWatched + } + } + bannerImage + mediaListOptions { + animeList { + sectionOrder + } + } + } + lists { + status + name + entries { + id + mediaId + status + progress + score + media { + id + status + title { + english + romaji + } + episodes + coverImage { + large + } + } + } + } + } + } + `, + variables: { + username: sessions?.user.name, + }, + }), + }); + + const dat = await response.json(); + + const prog = dat.data.MediaListCollection; + + const gat = prog?.lists.map((item) => item.entries); + const git = gat?.map((item) => + item?.find((item) => item.media.id === parseInt(aniId)) + ); + const gut = git?.find((item) => item?.media.id === parseInt(aniId)); + + if (gut?.status === "COMPLETED") { + setStatusWatch("REPEATING"); + } else if ( + gut?.status === "REPEATING" && + gut?.media?.episodes === parseInt(playingEpisode) + ) { + setStatusWatch("COMPLETED"); + } else if (gut?.status === "REPEATING") { + setStatusWatch("REPEATING"); + } else if (gut?.media?.episodes === parseInt(playingEpisode)) { + setStatusWatch("COMPLETED"); + } else if ( + gut?.media?.episodes !== null && + aniData.totalEpisodes === parseInt(playingEpisode) + ) { + setStatusWatch("COMPLETED"); + setLoading(true); + } + } + setLoading(true); + }; + fetchData(); + }, [id]); + + // console.log(fallback); + + const { Notification: NotificationComponent } = useNotification(); + + // console.log(); const [open, setOpen] = useState(false); const [aniStatus, setAniStatus] = useState(""); @@ -53,10 +250,12 @@ export default function Info({ info, sessions, statusWatch }) { console.log(formData); }; - const playingTitle = data.episodes - .filter((item) => item.id == info.id) + const playingTitle = data?.episodes + .filter((item) => item.id == id) .map((item) => item.title); + // console.log(skip); + return ( <> @@ -65,9 +264,9 @@ export default function Info({ info, sessions, statusWatch }) { - + {/* */} - setOpen(false)}> + {/* setOpen(false)}>

@@ -147,48 +346,34 @@ export default function Info({ info, sessions, statusWatch }) { )}

-
-
- -
-
-
- -
-
-
- {data.episodes.length > 0 ? ( - data.episodes - .filter((items) => items.id == info.id) - .map((item) => ( -
-
- - {item.title} - -
-

- Episode {item.number} -

-
- )) - ) : ( - <> - {fallback - .filter((item) => item.id == info.id) + */} + +
+ +
+
+ {loading ? ( +
+ +
+ ) : ( + + )} +
+ {data ? ( + data.episodes.length > 0 ? ( + data.episodes + .filter((items) => items.id == id) .map((item) => (
@@ -196,35 +381,72 @@ export default function Info({ info, sessions, statusWatch }) { href={`/anime/${data.id}`} className="inline hover:underline" > - {title} + {item.title}

Episode {item.number}

- ))} - + )) + ) : ( + <> + {fallback && + fallback + .filter((item) => item.id == id) + .map((item) => ( +
+
+ + {data.title.romaji || data.title.english} + +
+

+ Episode {item.number} +

+
+ ))} + + ) + ) : ( +
+
+
+ +
+
+

+ +

+
)} -
-
-
+
+
- Anime Cover + {data ? ( + Anime Cover + ) : ( + + )}

Studios

-
{data.studios}
+
+ {data ? data.studios : } +
setOpen(true)}> - {/* - Save to My List - */}
@@ -251,124 +470,147 @@ export default function Info({ info, sessions, statusWatch }) {

Status

-
{data.status}
+
{data ? data.status : }

Titles

-
- {data.title.romaji || ""} -
-
- {data.title.english || ""} -
-
- {data.title.native || ""} -
+ {data ? ( + <> +
+ {data.title.romaji || ""} +
+
+ {data.title.english || ""} +
+
+ {data.title.native || ""} +
+ + ) : ( + + )}
-
- {data.genres.map((item, index) => ( -
- {item} -
- ))} +
+ {data && + data.genres.map((item, index) => ( +
+ {item} +
+ ))}
-

+ {data && ( +

+ )}

-
-
-

- Up Next -

-
- {data.episodes.length > 0 - ? data.episodes.map((item) => { - return ( - -
- image +

+ Up Next +

+
+ {data ? ( + data.episodes.length > 0 ? ( + data.episodes.map((item) => { + return ( + +
+ image + + Episode {item.number} + + {item.id == id && ( +
+ + + +
+ )} +
+
- - Episode {item.number} - - {item.id == info.id && ( -
- - - -
- )} -
-
+

+ {item.title} +

+

+ {item.description} +

+
+ + ); + }) + ) : ( + fallback && + fallback.map((item) => { + return ( + -

- {item.title} -

-

- {item.description} -

-
- - ); - }) - : fallback.map((item) => { - return ( - - Episode {item.number} - - ); - })} + Episode {item.number} + + ); + }) + ) + ) : ( +
+ {[1, 2, 3].map((item) => ( + + ))} +
+ )} +
-
+ ); } @@ -385,162 +627,12 @@ export async function getServerSideProps(context) { const id = info[0]; const aniId = info[1]; - let epiFallback = null; - - const res = await fetch(`https://api.moopa.my.id/meta/anilist/watch/${id}`); - const epiData = await res.json(); - - const res2 = await fetch( - `https://api.moopa.my.id/meta/anilist/info/${aniId}` - ); - const aniData = await res2.json(); - - if (aniData.episodes.length === 0) { - const res = await fetch( - `https://api.moopa.my.id/anime/gogoanime/${ - aniData.title.romaji || aniData.title.english - }` - ); - const data = await res.json(); - const match = closestMatch( - aniData.title.romaji, - data.results.map((item) => item.title) - ); - const anime = data.results.filter((item) => item.title === match); - if (anime.length !== 0) { - const infos = await fetch( - `https://api.moopa.my.id/anime/gogoanime/info/${anime[0].id}` - ).then((res) => res.json()); - epiFallback = infos.episodes; - } - } - - const playingEpisode = - aniData.episodes - .filter((item) => item.id == id) - .map((item) => item.number) || - epiFallback.episodes - .filter((item) => item.id == id) - .map((item) => item.number); - - const response = await fetch("https://graphql.anilist.co/", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - query: ` - query ($username: String, $status: MediaListStatus) { - MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { - user { - id - name - about (asHtml: true) - createdAt - avatar { - large - } - statistics { - anime { - count - episodesWatched - meanScore - minutesWatched - } - } - bannerImage - mediaListOptions { - animeList { - sectionOrder - } - } - } - lists { - status - name - entries { - id - mediaId - status - progress - score - media { - id - status - title { - english - romaji - } - episodes - coverImage { - large - } - } - } - } - } - } - `, - variables: { - username: session?.user.name, - }, - }), - }); - - const dat = await response.json(); - - const prog = dat.data.MediaListCollection; - - const gat = prog?.lists.map((item) => item.entries); - const git = gat?.map((item) => - item.find((item) => item.media.id === parseInt(aniId)) - ); - const gut = git?.find((item) => item?.media.id === parseInt(aniId)); - - let statusWatch = "CURRENT"; - - if (gut?.status === "COMPLETED") { - statusWatch = "REPEATING"; - } else if ( - gut?.status === "REPEATING" && - gut?.media?.episodes === parseInt(playingEpisode) - ) { - statusWatch = "COMPLETED"; - } else if (gut?.status === "REPEATING") { - statusWatch = "REPEATING"; - } else if (gut?.media?.episodes === parseInt(playingEpisode)) { - statusWatch = "COMPLETED"; - } else if ( - gut?.media?.episodes !== null && - aniData.totalEpisodes === parseInt(playingEpisode) - ) { - statusWatch = "COMPLETED"; - } - - const res4 = await fetch( - `https://api.aniskip.com/v2/skip-times/${aniData.malId}/${parseInt( - playingEpisode - )}?types[]=ed&types[]=mixed-ed&types[]=mixed-op&types[]=op&types[]=recap&episodeLength=` - ); - const skip = await res4.json(); - - const op = skip.results?.find((item) => item.skipType === "op") || null; - const ed = skip.results?.find((item) => item.skipType === "ed") || null; return { props: { - info: { - id, - epiData, - aniData, - epiFallback, - skip: { - op: op, - ed: ed, - }, - }, sessions: session, - statusWatch: statusWatch, + id, + aniId, }, }; } -- cgit v1.2.3